import os
import sys
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from PyPDF2 import PdfReader, PdfWriter
from PIL import Image, ImageTk  # 用于图片处理和预览
import tempfile
import shutil
import glob
from tkinterdnd2 import DND_FILES, TkinterDnD
import fitz  # PyMuPDF库

class PDFEditor(TkinterDnD.Tk):
    def __init__(self):
        super().__init__()
        # 初始化环境变量和图标
        self.setup_environment()
        self.setup_icon()
        
        self.title("PDF编辑工具 v20250906.00")
        self.geometry("1000x700")
        self.configure(bg="#f0f0f0")
        
        # 设置中文字体支持
        self.style = ttk.Style()
        self.style.configure("TButton", font=("SimHei", 10))
        self.style.configure("TLabel", font=("SimHei", 10), background="#f0f0f0")
        self.style.configure("TListbox", font=("SimHei", 10))
        
        # 创建主框架
        self.main_frame = ttk.Frame(self, padding="10")
        self.main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 当前预览页码（0-based索引）
        self.current_preview_page = 0
        # 当前预览的PDF总页数
        self.total_preview_pages = 0
        # 当前预览的文件路径
        self.current_preview_file = None
        # 存储原始预览图像，用于窗口调整时重新缩放
        self.original_preview_image = None
        
        # 创建文件列表和预览区域
        self.create_main_layout()
        
        # 创建操作按钮区域
        self.create_operation_buttons()
        
        # 创建状态区域
        self.create_status_area()
        
        # 存储文件路径（PDF和图片）
        self.files = []
        # 存储临时文件路径
        self.temp_files = []
        # 存储预览图片对象，防止被垃圾回收
        self.preview_images = []
        
        # 绑定窗口大小改变事件，添加延迟处理防止频繁刷新
        self.bind("<Configure>", self.on_window_resize)
        self.resize_timer = None
        self.resize_delay = 100  # 调整大小后的延迟毫秒数
        
        # 移除了poppler相关检查代码

    def setup_environment(self):
        """设置环境变量"""
        # 获取程序根目录
        if getattr(sys, 'frozen', False):
            self.root_dir = os.path.dirname(sys.executable)
        else:
            self.root_dir = os.path.dirname(os.path.abspath(__file__))
    
    def setup_icon(self):
        """设置程序图标"""
        try:
            icon_path = os.path.join(self.root_dir, "icon.ico")
            if os.path.exists(icon_path):
                self.iconbitmap(icon_path)
        except Exception as e:
            pass
            # print(f"设置图标时出错: {str(e)}")
    
    def create_main_layout(self):
        """创建文件列表和预览区域的布局"""
        main_content = ttk.Frame(self.main_frame)
        main_content.pack(fill=tk.BOTH, expand=True)
        
        # 文件列表区域（左侧）
        list_frame = ttk.Frame(main_content, width=300)
        list_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=False, padx=(0, 10))
        
        ttk.Label(list_frame, text="文件列表 (支持PDF和图片，可拖拽添加)").pack(anchor=tk.W, pady=(0, 5))
        
        listbox_frame = ttk.Frame(list_frame)
        listbox_frame.pack(fill=tk.BOTH, expand=True)
        
        self.file_listbox = tk.Listbox(listbox_frame, selectmode=tk.EXTENDED, height=20)
        self.file_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        scrollbar = ttk.Scrollbar(listbox_frame, orient=tk.VERTICAL, command=self.file_listbox.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        self.file_listbox.config(yscrollcommand=scrollbar.set)
        
        # 绑定列表框选择事件，用于预览
        self.file_listbox.bind('<<ListboxSelect>>', self.on_file_select)
        
        # 启用拖放功能
        self.file_listbox.drop_target_register(DND_FILES)
        self.file_listbox.dnd_bind('<<Drop>>', self.on_drop)
        
        # 预览区域（右侧）
        preview_frame = ttk.Frame(main_content)
        preview_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
        
        # 预览标题和导航
        preview_header = ttk.Frame(preview_frame)
        preview_header.pack(fill=tk.X, pady=(0, 5))
        
        ttk.Label(preview_header, text="文件预览").pack(side=tk.LEFT, anchor=tk.W)
        
        # 页码导航控件
        nav_frame = ttk.Frame(preview_header)
        nav_frame.pack(side=tk.RIGHT)
        
        self.prev_button = ttk.Button(nav_frame, text="上一页", command=self.prev_page)
        self.prev_button.pack(side=tk.LEFT, padx=2)
        
        # 页面跳转控件
        jump_frame = ttk.Frame(nav_frame)
        ttk.Label(jump_frame, text="页码:").pack(side=tk.LEFT)
        self.page_entry = ttk.Entry(jump_frame, width=5)
        self.page_entry.pack(side=tk.LEFT, padx=2)
        self.page_entry.bind('<Return>', lambda e: self.jump_to_page())
        ttk.Label(jump_frame, text="/").pack(side=tk.LEFT, padx=(2, 0))
        self.total_pages_label = ttk.Label(jump_frame, text="0")
        self.total_pages_label.pack(side=tk.LEFT)
        ttk.Button(jump_frame, text="跳转", command=self.jump_to_page).pack(side=tk.LEFT, padx=2)
        jump_frame.pack(side=tk.LEFT, padx=5)
        
        self.next_button = ttk.Button(nav_frame, text="下一页", command=self.next_page)
        self.next_button.pack(side=tk.LEFT, padx=2)
        
        # 禁用初始导航按钮
        self.prev_button.config(state=tk.DISABLED)
        self.next_button.config(state=tk.DISABLED)
        
        # 预览画布
        self.preview_canvas_frame = ttk.Frame(preview_frame)
        self.preview_canvas_frame.pack(fill=tk.BOTH, expand=True)
        
        # 预览画布的滚动条
        preview_scroll_x = ttk.Scrollbar(self.preview_canvas_frame, orient=tk.HORIZONTAL)
        preview_scroll_x.pack(side=tk.BOTTOM, fill=tk.X)
        
        preview_scroll_y = ttk.Scrollbar(self.preview_canvas_frame, orient=tk.VERTICAL)
        preview_scroll_y.pack(side=tk.RIGHT, fill=tk.Y)
        
        self.preview_canvas = tk.Canvas(self.preview_canvas_frame, 
                                       xscrollcommand=preview_scroll_x.set,
                                       yscrollcommand=preview_scroll_y.set,
                                       bg="white")
        self.preview_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        preview_scroll_x.config(command=self.preview_canvas.xview)
        preview_scroll_y.config(command=self.preview_canvas.yview)
    
    def create_operation_buttons(self):
        # 按钮框架
        button_frame = ttk.Frame(self.main_frame)
        button_frame.pack(fill=tk.X, pady=(10, 10))
        
        # 添加文件按钮
        ttk.Button(button_frame, text="添加文件", command=self.add_files).pack(side=tk.LEFT, padx=5)
        
        # 移除文件按钮
        ttk.Button(button_frame, text="移除选中", command=self.remove_files).pack(side=tk.LEFT, padx=5)
        
        # 上移按钮
        ttk.Button(button_frame, text="上移", command=self.move_up).pack(side=tk.LEFT, padx=5)
        
        # 下移按钮
        ttk.Button(button_frame, text="下移", command=self.move_down).pack(side=tk.LEFT, padx=5)
        
        # 合并PDF按钮
        ttk.Button(button_frame, text="合并为PDF", command=self.merge_files).pack(side=tk.LEFT, padx=5)
        
        # 分割PDF按钮
        ttk.Button(button_frame, text="分割PDF", command=self.split_pdf).pack(side=tk.LEFT, padx=5)
    
    def create_status_area(self):
        # 状态标签
        self.status_var = tk.StringVar()
        self.status_var.set("就绪")
        ttk.Label(self.main_frame, textvariable=self.status_var).pack(anchor=tk.W)
    
    def on_file_select(self, event):
        """处理文件选择事件，显示预览"""
        selected_indices = self.file_listbox.curselection()
        if not selected_indices:
            return
        
        # 清除之前的预览
        self.clear_preview()
        
        # 获取选中的文件路径
        selected_index = selected_indices[0]
        file_path = self.files[selected_index]
        file_ext = os.path.splitext(file_path)[1].lower()
        
        # 重置页码导航状态
        self.current_preview_file = file_path
        self.current_preview_page = 0  # 使用0-based索引
        
        try:
            if file_ext == '.pdf':
                # 使用PyMuPDF打开PDF
                doc = fitz.open(file_path)
                self.total_preview_pages = len(doc)
                doc.close()  # 关闭文档
                
                self.update_page_navigation()
                self.load_preview_page(0)  # 直接加载页面
            else:
                # 对于图片，总页数为1
                self.total_preview_pages = 1
                self.update_page_navigation()
                self.preview_image(file_path)
        except Exception as e:
            self.preview_canvas.create_text(50, 50, text=f"预览失败: {str(e)}", fill="red")
    
    def prev_page(self):
        """显示上一页"""
        if self.current_preview_page > 0:
            self.load_preview_page(self.current_preview_page - 1)
            self.update_page_navigation()
    
    def next_page(self):
        """显示下一页"""
        if self.current_preview_page < self.total_preview_pages - 1:
            self.load_preview_page(self.current_preview_page + 1)
            self.update_page_navigation()
    
    def jump_to_page(self):
        """跳转到指定页码"""
        if not self.current_preview_file or self.total_preview_pages <= 1:
            return
            
        try:
            # 获取用户输入的页码（转换为0-based索引）
            page_num = int(self.page_entry.get().strip()) - 1
            
            # 验证页码有效性
            if 0 <= page_num < self.total_preview_pages:
                self.load_preview_page(page_num)
                self.update_page_navigation()
            else:
                messagebox.showwarning("警告", f"页码必须在1到{self.total_preview_pages}之间")
                self.page_entry.focus()
                
        except ValueError:
            messagebox.showwarning("警告", "请输入有效的页码")
            self.page_entry.focus()
    
    def update_page_navigation(self):
        """更新页码导航状态"""
        # 更新页码输入框和总页数显示（显示时转换为1-based）
        self.page_entry.delete(0, tk.END)
        self.page_entry.insert(0, str(self.current_preview_page + 1))
        self.total_pages_label.config(text=str(self.total_preview_pages))
        
        # 更新按钮状态
        self.prev_button.config(state=tk.NORMAL if self.current_preview_page > 0 else tk.DISABLED)
        self.next_button.config(state=tk.NORMAL if self.current_preview_page < self.total_preview_pages - 1 else tk.DISABLED)
    
    def on_window_resize(self, event):
        """窗口大小改变时重新缩放预览画面，添加延迟防止频繁刷新"""
        # 避免在窗口初始化时触发或非主窗口变化
        if event.widget != self or not self.current_preview_file:
            return
            
        # 取消之前的定时器
        if self.resize_timer:
            self.after_cancel(self.resize_timer)
            
        # 延迟执行，避免窗口调整过程中频繁刷新
        self.resize_timer = self.after(self.resize_delay, self.adjust_preview_for_resize)
    
    def adjust_preview_for_resize(self):
        """根据新的窗口大小调整预览图像"""
        if not self.current_preview_file or not self.original_preview_image:
            return
            
        try:
            file_ext = os.path.splitext(self.current_preview_file)[1].lower()
            
            # 使用原始图像重新计算缩放，避免多次缩放导致的质量损失
            img = self.original_preview_image.copy()
            
            # 获取当前画布大小
            canvas_width = self.preview_canvas.winfo_width()
            canvas_height = self.preview_canvas.winfo_height()
            
            # 减去边距
            max_width = max(100, canvas_width - 40)
            max_height = max(100, canvas_height - 40)
            
            # 计算缩放比例
            img_width, img_height = img.size
            scale = min(max_width / img_width, max_height / img_height, 1.0)
            
            # 缩放图片
            new_width = int(img_width * scale)
            new_height = int(img_height * scale)
            img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
            
            # 转换为Tkinter可用的图片格式
            tk_img = ImageTk.PhotoImage(img)
            
            # 保存图片引用，防止被垃圾回收
            self.preview_images.append(tk_img)
            
            # 在画布上显示图片
            self.preview_canvas.delete("all")
            self.preview_canvas.create_image(20, 20, anchor=tk.NW, image=tk_img)
            self.preview_canvas.config(scrollregion=(0, 0, new_width + 40, new_height + 40))
            
        except Exception as e:
            pass
    
    def preview_image(self, image_path):
        """预览图片文件，保存原始图像用于窗口调整时重新缩放"""
        try:
            with Image.open(image_path) as img:
                # 保存原始图像的副本，用于后续缩放
                self.original_preview_image = img.copy()
                
                # 调整图片大小以适应预览区域
                canvas_width = self.preview_canvas.winfo_width()
                canvas_height = self.preview_canvas.winfo_height()
                
                # 减去边距
                max_width = max(100, canvas_width - 40)
                max_height = max(100, canvas_height - 40)
                
                # 计算缩放比例
                img_width, img_height = img.size
                scale = min(max_width / img_width, max_height / img_height, 1.0)
                
                new_width = int(img_width * scale)
                new_height = int(img_height * scale)
                
                # 缩放图片
                img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
                
                # 转换为Tkinter可用的图片格式
                tk_img = ImageTk.PhotoImage(img)
                self.preview_images.append(tk_img)  # 保存引用
                
                # 清除之前的内容并显示新图片
                self.preview_canvas.delete("all")
                self.preview_canvas.create_image(20, 20, anchor=tk.NW, image=tk_img)
                
                # 设置画布滚动区域
                self.preview_canvas.config(scrollregion=(0, 0, new_width + 40, new_height + 40))
                
                self.update_status(f"正在预览图片: {os.path.basename(image_path)}")
        except Exception as e:
            self.update_status(f"无法预览图片: {str(e)}")
    
    def load_preview_page(self, page_num):
        """使用PyMuPDF加载并显示指定页码的预览，保存原始图像用于缩放"""
        try:
            # 使用PyMuPDF打开PDF
            doc = fitz.open(self.current_preview_file)
            
            # 检查页码有效性
            if page_num < 0 or page_num >= len(doc):
                raise Exception(f"无效的页码: {page_num + 1}")
            
            # 获取指定页
            page = doc.load_page(page_num)
            
            # 设置缩放比例（影响清晰度）
            zoom = 2.0
            mat = fitz.Matrix(zoom, zoom)
            
            # 渲染页面为图片
            pix = page.get_pixmap()
            
            # 将像素数据转换为PIL图像
            img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
            
            # 保存原始图像用于后续缩放
            self.original_preview_image = img.copy()
            
            # 调整图片大小以适应预览区域
            canvas_width = self.preview_canvas.winfo_width()
            canvas_height = self.preview_canvas.winfo_height()
            
            max_width = max(100, canvas_width - 40)
            max_height = max(100, canvas_height - 40)
            
            # 计算缩放比例
            img_width, img_height = img.size
            scale = min(max_width / img_width, max_height / img_height, 1.0)
            
            # 缩放图片
            new_width = int(img_width * scale)
            new_height = int(img_height * scale)
            img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
            
            # 转换为Tkinter可用的图片格式
            tk_img = ImageTk.PhotoImage(img)
            
            # 保存图片引用，防止被垃圾回收
            self.preview_images.append(tk_img)
            
            # 在画布上显示图片
            self.preview_canvas.delete("all")
            self.preview_canvas.create_image(20, 20, anchor=tk.NW, image=tk_img)
            self.preview_canvas.config(scrollregion=(0, 0, new_width + 40, new_height + 40))
            
            self.current_preview_page = page_num
            self.update_status(f"正在预览PDF: {os.path.basename(self.current_preview_file)} (第{page_num + 1}页)")
            
            # 关闭文档
            doc.close()
                
        except Exception as e:
            self.update_status(f"加载页面失败: {str(e)}")
            self.basic_pdf_preview(page_num)
    
    def basic_pdf_preview(self, page_num):
        """基础PDF预览（仅显示文本信息）"""
        try:
            # 使用PyMuPDF获取PDF信息
            doc = fitz.open(self.current_preview_file)
            text = f"PDF文件预览: {os.path.basename(self.current_preview_file)}\n"
            text += f"页码: {page_num + 1}/{len(doc)}\n\n"
            text += "提示: 无法提取PDF页面图像"
            
            self.preview_canvas.delete("all")
            self.preview_canvas.create_text(20, 20, anchor=tk.NW, text=text, width=400)
            self.preview_canvas.config(scrollregion=self.preview_canvas.bbox("all"))
            self.current_preview_page = page_num
            # 清除原始图像引用
            self.original_preview_image = None
            
            # 关闭文档
            doc.close()
        except Exception as e:
            self.update_status(f"基础预览失败: {str(e)}")
    
    def on_drop(self, event):
        # 处理拖放的文件
        files = self.tk.splitlist(event.data)
        valid_files = []
        
        for file in files:
            # 检查文件类型是否支持
            ext = os.path.splitext(file)[1].lower()
            if ext in ['.pdf', '.jpg', '.jpeg', '.png', '.bmp', '.gif']:
                if file not in self.files:
                    valid_files.append(file)
        
        if valid_files:
            for file in valid_files:
                self.files.append(file)
                # 显示文件名并标注类型
                filename = os.path.basename(file)
                ext = os.path.splitext(file)[1].lower()
                if ext == '.pdf':
                    self.file_listbox.insert(tk.END, f"{filename} (PDF)")
                else:
                    self.file_listbox.insert(tk.END, f"{filename} (图片)")
            
            self.update_status(f"已添加 {len(valid_files)} 个文件")
    
    def add_files(self):
        # 打开文件选择对话框添加文件（支持PDF和图片）
        files = filedialog.askopenfilenames(
            title="选择PDF或图片文件",
            filetypes=[
                ("支持的文件", "*.pdf;*.jpg;*.jpeg;*.png;*.bmp;*.gif"),
                ("PDF文件", "*.pdf"),
                ("图片文件", "*.jpg;*.jpeg;*.png;*.bmp;*.gif"),
                ("所有文件", "*.*")
            ]
        )
        
        if files:
            count = 0
            for file in files:
                if file not in self.files:
                    self.files.append(file)
                    # 显示文件名并标注类型
                    filename = os.path.basename(file)
                    ext = os.path.splitext(file)[1].lower()
                    if ext == '.pdf':
                        self.file_listbox.insert(tk.END, f"{filename} (PDF)")
                    else:
                        self.file_listbox.insert(tk.END, f"{filename} (图片)")
                    count += 1
            self.update_status(f"已添加 {count} 个文件")
    
    def remove_files(self):
        # 移除选中的文件
        selected_indices = self.file_listbox.curselection()
        if not selected_indices:
            messagebox.showwarning("警告", "请先选择要移除的文件")
            return
        
        # 从后往前删除，避免索引问题
        for i in sorted(selected_indices, reverse=True):
            del self.files[i]
            self.file_listbox.delete(i)
        
        # 清除预览
        self.clear_preview()
        
        self.update_status(f"已移除 {len(selected_indices)} 个文件")
    
    def move_up(self):
        # 上移选中的文件
        selected_indices = self.file_listbox.curselection()
        if not selected_indices or selected_indices[0] == 0:
            return
        
        for i in selected_indices:
            if i > 0:
                # 交换列表中的位置
                self.files[i], self.files[i-1] = self.files[i-1], self.files[i]
                # 交换列表框中的位置
                text = self.file_listbox.get(i)
                self.file_listbox.delete(i)
                self.file_listbox.insert(i-1, text)
                # 更新选中状态
                self.file_listbox.selection_clear(i)
                self.file_listbox.selection_set(i-1)
        
        self.update_status("文件已上移")
    
    def move_down(self):
        # 下移选中的文件
        selected_indices = self.file_listbox.curselection()
        if not selected_indices or selected_indices[-1] == self.file_listbox.size() - 1:
            return
        
        # 从后往前处理，避免索引问题
        for i in sorted(selected_indices, reverse=True):
            if i < self.file_listbox.size() - 1:
                # 交换列表中的位置
                self.files[i], self.files[i+1] = self.files[i+1], self.files[i]
                # 交换列表框中的位置
                text = self.file_listbox.get(i)
                self.file_listbox.delete(i)
                self.file_listbox.insert(i+1, text)
                # 更新选中状态
                self.file_listbox.selection_clear(i)
                self.file_listbox.selection_set(i+1)
        
        self.update_status("文件已下移")
    
    def clear_preview(self):
        """清除预览区域"""
        self.preview_canvas.delete("all")
        self.preview_images.clear()
        self.original_preview_image = None  # 清除原始图像引用
        self.current_preview_file = None
        self.current_preview_page = 0
        self.total_preview_pages = 0
        self.page_entry.delete(0, tk.END)
        self.page_entry.insert(0, "1")
        self.total_pages_label.config(text="0")
        self.prev_button.config(state=tk.DISABLED)
        self.next_button.config(state=tk.DISABLED)
    
    def image_to_pdf(self, image_path, output_path):
        """将图片转换为PDF文件"""
        try:
            with Image.open(image_path) as img:
                # 转换为RGB模式（处理透明通道）
                if img.mode in ('RGBA', 'LA') or (img.mode == 'P' and 'transparency' in img.info):
                    background = Image.new(img.mode[:-1], img.size, (255, 255, 255))
                    background.paste(img, img.split()[-1])
                    img = background
                
                # 保存为PDF
                img.save(output_path, "PDF", resolution=100.0, save_all=True)
            return True
        except Exception as e:
            return False
    
    def merge_files(self):
        # 合并PDF和图片文件
        if len(self.files) < 1:
            messagebox.showwarning("警告", "请至少选择1个文件进行合并")
            return
        
        # 询问保存位置
        output_path = filedialog.asksaveasfilename(
            defaultextension=".pdf",
            filetypes=[("PDF文件", "*.pdf"), ("所有文件", "*.*")],
            title="保存合并后的PDF"
        )
        
        if not output_path:
            return
        
        try:
            self.update_status("正在处理文件...")
            self.update_idletasks()
            
            # 创建临时目录保存转换的图片PDF
            temp_dir = tempfile.mkdtemp()
            self.temp_files.append(temp_dir)
            
            pdf_writer = PdfWriter()
            
            for i, file_path in enumerate(self.files):
                ext = os.path.splitext(file_path)[1].lower()
                
                # 显示当前处理进度
                filename = os.path.basename(file_path)
                self.update_status(f"正在处理: {filename} ({i+1}/{len(self.files)})")
                self.update_idletasks()
                
                if ext == '.pdf':
                    # 直接处理PDF文件
                    pdf_reader = PdfReader(file_path)
                    for page in pdf_reader.pages:
                        pdf_writer.add_page(page)
                else:
                    # 处理图片文件：先转换为PDF
                    temp_pdf_path = os.path.join(temp_dir, f"image_{i}.pdf")
                    if not self.image_to_pdf(file_path, temp_pdf_path):
                        raise Exception(f"无法处理图片: {filename}")
                    
                    # 将转换后的PDF添加到合并列表
                    pdf_reader = PdfReader(temp_pdf_path)
                    for page in pdf_reader.pages:
                        pdf_writer.add_page(page)
            
            # 写入最终的PDF文件
            with open(output_path, 'wb') as out:
                pdf_writer.write(out)
            
            self.update_status(f"文件已成功合并到: {os.path.basename(output_path)}")
            messagebox.showinfo("成功", f"文件已成功合并到:\n{output_path}")
            
        except Exception as e:
            self.update_status(f"合并失败: {str(e)}")
            messagebox.showerror("错误", f"合并时发生错误:\n{str(e)}")
        finally:
            # 清理临时文件
            self.cleanup_temp_files()
    
    def split_pdf(self):
        # 分割PDF文件（仅处理PDF）
        if len(self.files) != 1:
            messagebox.showwarning("警告", "请选择一个PDF文件进行分割")
            return
        
        file_path = self.files[0]
        if not file_path.lower().endswith('.pdf'):
            messagebox.showwarning("警告", "请选择一个PDF文件进行分割")
            return
        
        # 创建分割设置对话框
        dialog = tk.Toplevel(self)
        dialog.title("分割PDF设置")
        dialog.geometry("300x200")
        dialog.transient(self)
        dialog.grab_set()
        
        # 每页分割选项
        ttk.Label(dialog, text="分割方式:").pack(anchor=tk.W, pady=(10, 5))
        
        split_var = tk.IntVar(value=1)
        
        ttk.Radiobutton(dialog, text="按每一页分割", variable=split_var, value=1).pack(anchor=tk.W, padx=20)
        ttk.Radiobutton(dialog, text="指定页码范围", variable=split_var, value=2).pack(anchor=tk.W, padx=20)
        
        # 页码范围输入框
        range_frame = ttk.Frame(dialog)
        ttk.Label(range_frame, text="页码范围 (例如: 1-3,5)").pack(side=tk.LEFT)
        range_entry = ttk.Entry(range_frame, width=20)
        range_entry.pack(side=tk.LEFT, padx=5)
        range_frame.pack(anchor=tk.W, padx=20, pady=10)
        
        # 确定按钮
        def confirm_split():
            split_type = split_var.get()
            
            # 选择保存目录
            output_dir = filedialog.askdirectory(title="选择保存分割文件的目录")
            if not output_dir:
                dialog.destroy()
                return
            
            try:
                self.update_status("正在分割PDF文件...")
                self.update_idletasks()
                
                pdf_reader = PdfReader(file_path)
                total_pages = len(pdf_reader.pages)
                file_name = os.path.splitext(os.path.basename(file_path))[0]
                
                if split_type == 1:
                    # 按每一页分割
                    for i in range(total_pages):
                        pdf_writer = PdfWriter()
                        pdf_writer.add_page(pdf_reader.pages[i])
                        
                        output_path = os.path.join(output_dir, f"{file_name}_page_{i+1}.pdf")
                        with open(output_path, 'wb') as out:
                            pdf_writer.write(out)
                    
                    self.update_status(f"PDF文件已分割为 {total_pages} 个文件")
                    messagebox.showinfo("成功", f"PDF文件已分割为 {total_pages} 个文件，保存到:\n{output_dir}")
                
                else:
                    # 按指定页码范围分割
                    range_str = range_entry.get().strip()
                    if not range_str:
                        messagebox.showwarning("警告", "请输入页码范围")
                        return
                    
                    ranges = self.parse_page_ranges(range_str, total_pages)
                    if not ranges:
                        return
                    
                    for i, (start, end) in enumerate(ranges):
                        pdf_writer = PdfWriter()
                        for page_num in range(start-1, end):  # 转换为0-based索引
                            pdf_writer.add_page(pdf_reader.pages[page_num])
                        
                        output_path = os.path.join(output_dir, f"{file_name}_pages_{start}-{end}.pdf")
                        with open(output_path, 'wb') as out:
                            pdf_writer.write(out)
                    
                    self.update_status(f"PDF文件已分割为 {len(ranges)} 个文件")
                    messagebox.showinfo("成功", f"PDF文件已分割为 {len(ranges)} 个文件，保存到:\n{output_dir}")
                
            except Exception as e:
                self.update_status(f"分割失败: {str(e)}")
                messagebox.showerror("错误", f"分割PDF时发生错误:\n{str(e)}")
            
            dialog.destroy()
        
        ttk.Button(dialog, text="确定", command=confirm_split).pack(pady=10)
        
        # 居中显示对话框
        dialog.update_idletasks()
        width = dialog.winfo_width()
        height = dialog.winfo_height()
        x = (self.winfo_width() // 2) - (width // 2) + self.winfo_x()
        y = (self.winfo_height() // 2) - (height // 2) + self.winfo_y()
        dialog.geometry(f"+{x}+{y}")
    
    def parse_page_ranges(self, range_str, total_pages):
        """解析页码范围字符串，如"1-3,5,7-9"并返回页码范围列表"""
        ranges = []
        parts = range_str.split(',')
        
        for part in parts:
            part = part.strip()
            if '-' in part:
                try:
                    start, end = map(int, part.split('-'))
                    if start < 1 or end > total_pages or start > end:
                        raise ValueError
                    ranges.append((start, end))
                except ValueError:
                    messagebox.showwarning("警告", f"无效的页码范围: {part}")
                    return None
            else:
                try:
                    page = int(part)
                    if page < 1 or page > total_pages:
                        raise ValueError
                    ranges.append((page, page))
                except ValueError:
                    messagebox.showwarning("警告", f"无效的页码: {part}")
                    return None
        
        return ranges
    
    def cleanup_temp_files(self):
        """清理临时文件"""
        image_files = glob.glob(os.path.join("page-*.png"))
        for f in image_files:
            if f:
                os.remove(f)
        for temp_path in self.temp_files:
            try:
                if os.path.isfile(temp_path):
                    os.remove(temp_path)
                elif os.path.isdir(temp_path):
                    shutil.rmtree(temp_path)
            except Exception as e:
                pass
        
        self.temp_files = []
    
    def update_status(self, message):
        self.status_var.set(message)
    
    def on_close(self):
        """窗口关闭时清理临时文件"""
        self.cleanup_temp_files()
        self.destroy()

if __name__ == "__main__":
    # 检查是否安装了必要的库
    try:
        import PyPDF2
        from tkinterdnd2 import TkinterDnD
        from PIL import Image
        import fitz  # 检查PyMuPDF
    except ImportError as e:
        missing_lib = str(e).split("'")[1]
        sys.exit(1)
    
    app = PDFEditor()
    app.protocol("WM_DELETE_WINDOW", app.on_close)  # 窗口关闭时清理临时文件
    app.mainloop()
